package ferus.tigris.lines;

import java.util.ArrayDeque;
import java.util.Deque;

import ferus.tigris.lines.views.NumberView;
import ferus.tigris.lines.views.ShowResultsButton;
import ferus.tigris.lines.views.TopResultsView;
import ferus.tigris.lines.personages.AbstractBehavior;
import ferus.tigris.lines.data.Config;
import ferus.tigris.lines.data.DB;
import ferus.tigris.lines.views.*;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class GameView extends SurfaceView implements OnTouchListener {
	private SurfaceHolder holder;
	private GameDrawManager gameDrawManager = new GameDrawManager(this);
	private GameManager gameManager = new GameManager(this);
	
	Matrix sprites = new Matrix();
	private SoundToggle soundToggleButton;
	private CommonStatisticView statistic = null;
	
	private BackgroundView background;
	private ForegroundView foreground;
	private TopResultsView topResults = new TopResultsView(this);
	private ShowResultsButton showResultsButton = new ShowResultsButton(this);
	private NumberView number = new NumberView(this);
	private float scaledDensity = 1;
	
	private SoundManager sounds;
	private Deque<AbstractBehavior> queue = new ArrayDeque<AbstractBehavior>();
	GameFieldActivity activity = null;
	
	public GameView(GameFieldActivity context) {
		super(context);
		init(context, scaledDensity);
	}
	
	public GameView(GameFieldActivity context, float scaledDensity) {
		super(context);
		init(context, scaledDensity);
	}

	protected void init(GameFieldActivity context, float scaledDensity) {
		this.scaledDensity = scaledDensity;

		holder = getHolder();
		setOnTouchListener(this);
		holder.addCallback(new SurfaceHolder.Callback() {

			public void surfaceDestroyed(SurfaceHolder holder) {
				onSufaceDestroy();
			}

			public void surfaceCreated(SurfaceHolder holder) {
				onSufaceCreate();
			}

			public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
			}
		});
		
		sounds = new SoundManager(context);
		activity = context;
	}
	
	private void onSufaceCreate() {
		statistic = new CommonStatisticView(gameManager);
		soundToggleButton = new SoundToggle(this);

		foreground = new ForegroundView(this);
		background = new BackgroundView(this);

		if(gameDrawManager.getState() == Thread.State.NEW) {
			gameDrawManager.setRunning(true);
			gameDrawManager.start();
		}
		if(gameManager.getState() == Thread.State.NEW) {
			gameManager.setRunning(true);
			gameManager.start();
		}
	}

	private void onSufaceDestroy() {}
	
	protected void onDraw(Canvas canvas) {
		placeButtons();
		
		background.draw(canvas);
		foreground.draw(canvas);

		for(AbstractBehavior sprite: sprites.getMarks()) {
			if(sprite != null)
				sprite.draw(canvas);
		}
		
		for(AbstractBehavior sprite: queue) {
			if(sprite != null)
				sprite.draw(canvas);
		}
		
		
		soundToggleButton.draw(canvas, sounds.enable());
		statistic.draw(canvas);
		showResultsButton.draw(canvas);
		number.draw(gameManager.scope(), canvas);
		topResults.draw(canvas);
	}

	protected void placeButtons() {
		int x = getWidth();
		int y = getHeight() - showResultsButton.height();
		
		x -= soundToggleButton.width();
		y = getHeight() - soundToggleButton.height();
		soundToggleButton.setPosition(new Point(x, y));

		x -= showResultsButton.width();
		y = getHeight() - showResultsButton.height();
		showResultsButton.setPosition(new Point(x, y));
		
		/*x -= resetButton.width(); 
		y = getHeight() - resetButton.height();
		resetButton.setPosition(new Point(x, y));*/
		
		y = getHeight() - number.height();
		number.setPosition(new Point(0, y));
	}

	public boolean onTouch(View v, MotionEvent event) {
		int act = event.getAction();
		if(act == MotionEvent.ACTION_UP) {
			gameManager.onTouch(event.getX(), event.getY());
			if(soundToggleButton.isCollition(event.getX(),event.getY())) {
				sounds.setEnabled(!sounds.enable());
			}
			if(showResultsButton.isCollition(event.getX(), event.getY())) {
				showResultsButton.press(gameManager);
			}
			/*if(resetButton.isCollition(event.getX(),event.getY())) {
			resetButton.press(gameManager);
		}*/
		}
		if(act == MotionEvent.ACTION_DOWN) {
			if(topResults.isCollition((int)event.getX(), (int)event.getY())) {
				topResults.show(false);
				return false;
			}
		}
		return true;
	}

	public float getScale() {
		return scaledDensity;
	}

	public Rect gameField() {
		int y = getWidth()/6;
		Rect screen = new Rect(0, y, getWidth(), y + getWidth());
		return screen;
	}

	public SoundManager sounds() {
		return sounds;
	}

	public void setSprites(Matrix marks, Deque<AbstractBehavior> queue) {
		this.sprites = marks;
		this.queue = queue;
	}

	public void load(DB db, Config conf) {
		sounds.setEnabled(conf.isSoundEnable());
		gameManager.load(db);
		topResults.load(db);
	}

	public void save(DB db, Config conf) {
		conf.setSoundEnabled(sounds.enable());
		gameManager.save(db);
	}

	public void stop() {
		gameDrawManager.setRunning(false);
		gameManager.setRunning(false);
	}

	public Integer scope() {
		return gameManager.scope();
	}

	public void showTopTable() {
		topResults.show(!topResults.isVisible());
	}

	public void saveResult() {
		activity.saveResult();
	}

	public void saveResult(DB db) {
		gameManager.saveResult(db);
		topResults.load(db);
	}
}